package com.fsnbigdata.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;

public class DateUtil {
    // 获得某天最大时间 2017-10-15 23:59:59
    public static Date getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());;
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    // 获得某天最小时间 2017-10-15 00:00:00
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    //获取指定的时间
    public static Date getAppointDate(String dateStr,String dateFormat){
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 获取指定日期所在月份开始的时间戳
     * @param date 指定日期
     * @return
     */
    public static Long getMonthBegin(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND,0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);
        // 获取本月第一天的时间戳
        return c.getTimeInMillis();
    }

    /**
     * 获取指定日期所在月份结束的时间戳
     * @param date 指定日期
     * @return
     */
    public static Long getMonthEnd(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);

        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c.set(Calendar.MINUTE, 59);
        //将秒至59
        c.set(Calendar.SECOND,59);
        //将毫秒至999
        c.set(Calendar.MILLISECOND, 999);
        // 获取本月最后一天的时间戳
        return c.getTimeInMillis();
    }

    //获取本地的时间
    public static Date getLocalDate(){
        LocalDateTime time = LocalDateTime.now();
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = time.atZone(zone).toInstant();
        Date date = Date.from(instant);
        return date;
    }

    //获取list时间段
    public static List<Map> getTime(String startTime, String endTime){
        Long sTime = Long.parseLong(startTime);
        Long eTime = Long.parseLong(endTime);
        Calendar c = Calendar.getInstance();
        Long seTime = eTime-sTime;     //时间差
        Long day = 24L*60*60*1000;
        Long week = 12L*24*60*60*1000;
        Long month = 3L*28*24*60*60*1000;
        Long year = 12L*30*24*60*60*1000;
        List<Map> list = new ArrayList();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = getStartOfDay(new Date(sTime));
        if(seTime<week){
            int m = ((Long)(seTime/day)).intValue();
            for(int i = 0;i<=m;i++){
                Map map = new HashMap();
                c.setTime(new Date(sTime));
                c.add(Calendar.DATE, i);
                Date d = c.getTime();
                if(getStartOfDay(d).getTime()<=eTime){
                    map.put("startTime",getStartOfDay(d).getTime());
                    map.put("endTime",getEndOfDay(d).getTime());
                    map.put("formatDate",formatter.format(d));
                }
                list.add(map);
            }
        }
        if(seTime<month&&seTime>=week){
            int m = 1;
            while (true){
                Map map = new HashMap();
                c.setTime(new Date(sTime));
                c.add(Calendar.DAY_OF_WEEK, m*7 );
                Date d = new Date(getStartOfDay(c.getTime()).getTime()-1);
                if(d.getTime()<=eTime){
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(d).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(getEndOfDay(d)));
                }else {
                    if(date.getTime()>eTime){
                        break;
                    }
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(new Date(eTime)).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(eTime));
                }
                list.add(map);
                date = new Date(getEndOfDay(d).getTime()+1);
                m++;
            }
        }
        if(seTime>=month&&seTime<=year){
            int m = 1;
            while (true){
                Map map = new HashMap();
                c.setTime(new Date(sTime));
                c.add(Calendar.DAY_OF_WEEK, m*28);
                Date d = new Date(getStartOfDay(c.getTime()).getTime()-1);
                if(d.getTime()<=eTime){
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(d).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(getEndOfDay(d)));
                }else {
                    if(date.getTime()>eTime){
                        break;
                    }
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(new Date(eTime)).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(eTime));
                }
                list.add(map);
                date = new Date(getEndOfDay(d).getTime()+1);
                m++;
            }
        }
        if(seTime>year){
            int m = 1;
            while (true){
                Map map = new HashMap();
                c.setTime(new Date(sTime));
                c.add(Calendar.YEAR, m);
                Date d = new Date(getStartOfDay(c.getTime()).getTime()-1);
   //             Date d = c.getTime();
                if(d.getTime()<=eTime){
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(d).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(getEndOfDay(d)));
                }else {
                    if(date.getTime()>eTime){
                        break;
                    }
                    map.put("startTime",getStartOfDay(date).getTime());
                    map.put("endTime",getEndOfDay(new Date(eTime)).getTime());
                    map.put("formatDate",formatter.format(date)+"~"+formatter.format(eTime));
                }
                list.add(map);
                date = new Date(getEndOfDay(d).getTime()+1);
                m++;
            }
        }
        return list;
    }
}
